home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / LinkSrcB.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  37.0 KB  |  1,193 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSrcB.cpp
  3.  
  4.     Contains:    Implementation of ODBaseLinkSource class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     3/26/96    CC        1332880: kODLinkContent should use std ISO
  13.                                     prefix.
  14.         <50>     10/8/95    TJ        Fixes Recomended by Refball
  15.         <49>     10/5/95    CC        1241300: Clear removes data interchange
  16.                                     properties.
  17.         <48>     10/3/95    TJ        Added Includes so it compiles
  18.         <47>     10/3/95    TJ        Changes done by RefBall Team
  19.         <46>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  20.                                     without kOD prefix!
  21.         <45>      9/1/95    CC        1280757: Throw kODErrBrokenLink instead of
  22.                                     kODErrBrokenLinkSource.
  23.         <44>     8/30/95    EL        1279582: Storage ODVolatile problems.
  24.         <43>     8/29/95    DM        1221778, 1276165: add LinkUpdateAlert-
  25.                                     Completed, fUpdatedAfterSuspended,
  26.                                     fSuspended, and change Unlock to let
  27.                                     LinkMgr show update alerts.
  28.         <42>     8/21/95    VL        1277291: Added #include <StorUtil.h>.
  29.         <41>     8/12/95    TÇ        1276807 Opt./Bug: use StdTypIO routines for
  30.                                     portable streaming & smaller footprint
  31.         <40>      8/3/95    RR        #1257260: Collapse B classes. Remove
  32.                                     somInit methods. Don't call IsInitialized
  33.                                     or SubclassResponsibility
  34.         <39>     7/28/95    CC        1183569: Externalize only when dirty.
  35.         <38>     7/28/95    CC        1242625: ODDeleteObject sets argument to
  36.                                     null.
  37.         <37>     7/27/95    CC        1266053: Unlock only fails if the key is
  38.                                     invalid.  Errors caused by notify ing
  39.                                     destinations are suppressed.
  40.                                     1272086: Unlock returns kODFalse if
  41.                                     returned key is null.
  42.                                     1266119: InitBaseLinkSource: Set fUpdateID
  43.                                     to a valid change ID, in case the initial
  44.                                     update of the link fails.
  45.         <36>     7/24/95    CC        1154714: Don't pass update id to
  46.                                     UpdateDependents.
  47.                                     Unlock: Set _fKindsUsed to kODNULL after
  48.                                     deleting.
  49.         <35>     7/20/95    CC        1270145: Clear: Fail immediately if draft
  50.                                     cannot be changed.
  51.         <34>     6/21/95    CC        1260937: BB: ODTypeListIterator must return
  52.                                     copies of ODType values.
  53.         <33>     6/19/95    CC        1260182 Lock: Return kODFalse if lock not
  54.                                     granted.
  55.         <32>     6/17/95    CC        1259902: Clear, ContentUpdated: Fail if id
  56.                                     is kODUnknownUpdate.
  57.                                     1252700: Clear: Inhibit notification if
  58.                                     cleared with existing update ID.
  59.         <31>     6/12/95    CC        1255414: Externalize, CloneInto: Write list
  60.                                     of types used if last update failed.
  61.                                     Lock: Delete iterator.
  62.                                     Added static function
  63.                                     RemovePromisedContent; called by
  64.                                     Externalize and CloneInto.
  65.         <30>      6/7/95    CC        1252870: Replaced kODKeyNotGranted with
  66.                                     local kODNullKey.
  67.         <29>      6/2/95    CC        1255474: GetLink: AcquireLink restored to
  68.                                     GetLink.
  69.         <28>     5/26/95    VL        1251403: Multithreading naming support.
  70.         <27>     5/18/95    CC        1250280: ShowLinkSourceInfo throws on
  71.                                     invalid null arguments.
  72.         <26>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  73.                                     refcount
  74.         <25>     5/16/95    CC        1246729: Clear removes the kODPropContents
  75.                                     property; promises for values in use
  76.                                     fulfilled in Unlock.
  77.         <24>     4/27/95    CC        1242550: Moved circular link detection from
  78.                                     ContentUpdated to Unlock.
  79.                                     Always set fChangeTime, even if change is
  80.                                     not propogated.
  81.                                     Removed private method IsChanged.
  82.         <23>     4/25/95    CC        1242555: Lock: $5 entered as bug 1242561.
  83.                                     1242555: Clear: Removed $5 comment.
  84.         <22>     4/16/95    VL        1230084: Use POUtils in Init,
  85.                                     InitFromStorage and CloneInto.
  86.         <21>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  87.                                     should take Environment* and SU* when
  88.                                     possible
  89.         <20>     4/11/95    CC        1235953: Lock link's storage unit, not its
  90.                                     content storage unit, to guard access to
  91.                                     link content.
  92.                                     1236452: Added SOM_CATCH to
  93.                                     InitBaseLinkSourceFromStorage.
  94.         <19>     3/22/95    CC        1230650: Clear() looks for content in wrong
  95.                                     storage unit.
  96.                                     1229648: Clear() and Externalize() remove
  97.                                     unfulfilled promises.
  98.         <18>      3/9/95    CC        1221471: Added changesAllowed parameter to
  99.                                     ShowLinkSourceInfo().
  100.         <17>     2/15/95    CC        1216124    ShowLinkSourceInfo: Aquire modal
  101.                                     focus & deactivate front window.
  102.         <16>     1/19/95    CC        1193551 Removed GetLinkStatus().
  103.                                     1212356 ShowSourceContent: Catch errors
  104.                                     returned by
  105.                                     ODLinkSource::ShowSourceContent().
  106.         <15>    12/22/94    CC        1207986 Moved ODSURemoveProperty to
  107.                                     StdTypIO.
  108.         <14>    12/16/94    CC        1203516 Removed ODLink parameter from
  109.                                     InitBaseLinkSource(); added SetLink().
  110.         <13>    12/15/94    CC        1205605 SetSourcePart() - Removed call to
  111.                                     SetChangedFromPrev().
  112.         <12>     10/7/94    CC        1160232 - Alert user of possible link cycle
  113.                                     when updating.
  114.         <11>     10/4/94    CC        1190307 - Robustify for non-existent link
  115.                                     object.
  116.         <10>     9/29/94    RA        1189812: Mods for 68K build.
  117.          <9>     9/15/94    CC         1186669 - Replace CloneTo() with
  118.                                     CloneInto().
  119.          <8>      9/8/94    CC        #1185565 - Fix Lock();
  120.                                     #1185113 - Use StdTypeIO to read/write
  121.                                     property values.
  122.          <7>      9/7/94    CC        #1185344 - Implement Lock() and Unlock()
  123.                                     using storage unit locks.
  124.          <6>     8/26/94    VL        1183174: Use updated cloning APIs.
  125.          <5>     8/16/94    TÇ        #1180922  Remove more obsolete types from
  126.                                     StdTypes.idl.  Localized kODLinkContent to
  127.                                     this file, changed usage of kODUpdateID to
  128.                                     kODULong which is what the format of an
  129.                                     ODUpdateID actually is.
  130.          <4>     8/12/94    CC        1180598 - Added ODFacet parameter to
  131.                                     ShowLinkSourceInfo().
  132.          <3>     8/10/94    CC        1179943 - Moved in platform-independent
  133.                                     implementation from LinkSrc.cpp.
  134.          <2>      8/5/94    CC        #1179160 - ContentUpdated() takes ODLinkKey
  135.                                     parameter.
  136.          <1>     6/24/94    CC        first checked in
  137.     To Do: 
  138. */
  139.  
  140. #define VARIABLE_MACROS
  141.  
  142. #define ODBaseLinkSource_Class_Source
  143. #include <LinkSrcB.xih>
  144.  
  145. #include <LinkSrc.xh>
  146.  
  147. #ifndef _EXCEPT_
  148. #include <Except.h>
  149. #endif
  150.  
  151. #ifndef _ODMEMORY_
  152. #include <ODMemory.h>
  153. #endif
  154.  
  155. #ifndef _CONSTDEF_
  156. #include <ConstDef.h>
  157. #endif
  158.  
  159. #ifndef SOM_ODLink_xh
  160. #include <Link.xh>
  161. #endif
  162.  
  163. #ifndef _LINKDLGS_
  164. #include <LinkDlgs.h>
  165. #endif
  166.  
  167. #ifndef SOM_ODPart_xh
  168. #include <Part.xh>
  169. #endif
  170.  
  171. #ifndef SOM_ODFrame_xh
  172. #include <Frame.xh>
  173. #endif
  174.  
  175. #ifndef SOM_ODContainer_xh
  176. #include <ODCtr.xh>
  177. #endif
  178.  
  179. #ifndef SOM_ODDocument_xh
  180. #include <Document.xh>
  181. #endif
  182.  
  183. #ifndef SOM_ODDraft_xh
  184. #include <Draft.xh>
  185. #endif
  186.  
  187. #ifndef SOM_ODSession_xh
  188. #include <ODSessn.xh>
  189. #endif
  190.  
  191. #ifndef SOM_ODArbitrator_xh
  192. #include <Arbitrat.xh>
  193. #endif
  194.  
  195. #ifndef SOM_ODWindowState_xh
  196. #include <WinStat.xh>
  197. #endif
  198.  
  199. #ifndef SOM_Module_OpenDoc_Foci_defined
  200. #include <Foci.xh>
  201. #endif
  202.  
  203. #ifndef SOM_ODStorageSystem_xh
  204. #include <ODStor.xh>
  205. #endif
  206.  
  207. #ifndef SOM_ODStorageUnit_xh
  208. #include <StorageU.xh>
  209. #endif
  210.  
  211. #ifndef SOM_Module_OpenDoc_StdProps_defined
  212. #include <StdProps.xh>
  213. #endif
  214.  
  215. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  216. #include <StdTypes.xh>
  217. #endif
  218.  
  219. #ifndef __ERRORS__
  220. #include <Errors.h>
  221. #endif
  222.  
  223. #ifndef _ODUTILS_
  224. #include <ODUtils.h>
  225. #endif
  226.  
  227. /* Adkins -- added to provide prototype for ODUnused and LMGetBufPtr */
  228. /* Adkins -- LMGetBufPtr is in LowMem.h, which PlfmDef.h conditionaly includes */
  229. #ifndef _PLFMDEF_
  230. #include <PlfmDef.h>
  231. #endif
  232.  
  233. #ifndef _ISOSTR_
  234. #include <ISOStr.h>
  235. #endif
  236.  
  237. #ifndef _DOCUTILS_
  238. #include <DocUtils.h>
  239. #endif
  240.  
  241. #ifndef _STDTYPIO_
  242. #include <StdTypIO.h>
  243. #endif
  244.  
  245. #ifndef _ODDEBUG_
  246. #include <ODDebug.h>
  247. #endif
  248.  
  249. #ifndef _POUTILS_
  250. #include <POUtils.h>
  251. #endif
  252.  
  253. #ifndef SOM_ODTypeList_xh
  254. #include <TypeList.xh>
  255. #endif
  256.  
  257. #ifndef SOM_LinkMgr_xh
  258. #include <LinkMgr.xh>
  259. #endif
  260.  
  261. #ifndef SOM_ODTypeListIterator_xh
  262. #include <TypLsItr.xh>
  263. #endif
  264.  
  265. #ifndef _STORUTIL_
  266. #include <StorUtil.h>
  267. #endif
  268.  
  269. #ifndef _TEMPOBJ_
  270. #include "TempObj.h"
  271. #endif
  272.  
  273. #pragma segment ODBaseLinkSource
  274.  
  275. //==============================================================================
  276. // Constants
  277. //==============================================================================
  278.  
  279. const    ODType    kODLinkContent    = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:ObjectType:LinkContent";
  280. const    ODULong    kODNullKey         = 0;
  281.  
  282. // dirty masks
  283. const ODULong kNotDirty                    = 0x0000UL;
  284. const ODULong kLinkDirty                = 0x0001UL;
  285. const ODULong kSourcePartDirty            = 0x0002UL;
  286. const ODULong kAutoUpdateDirty            = 0x0004UL;
  287. const ODULong kUpdateIDDirty            = 0x0008UL;
  288. const ODULong kChangeTimeDirty            = 0x0010UL;
  289. const ODULong kKindsUsedDirty            = 0x0020UL;
  290. const ODULong kContentSUDirty            = 0x0040UL;
  291. const ODULong kChangeLimitDirty            = 0x0080UL;
  292. const ODULong kAllDirty                    = 0xFFFFUL;
  293.  
  294. //==============================================================================
  295. // Local functions
  296. //==============================================================================
  297.  
  298. static void RemovePromisedContent(Environment *ev, ODStorageUnit* su);
  299.  
  300. //==============================================================================
  301. // ODBaseLinkSource
  302. //==============================================================================
  303.  
  304. //------------------------------------------------------------------------------
  305. // ODBaseLinkSource: somInit
  306. //------------------------------------------------------------------------------
  307.  
  308. SOM_Scope void  SOMLINK ODBaseLinkSourcesomInit(ODBaseLinkSource *somSelf)
  309. {
  310.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  311.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somInit");
  312.  
  313.     parent_somInit(somSelf);
  314.  
  315.     _fContentSU = (ODStorageUnit*) kODNULL;
  316.     _fLink = (ODLink*) kODNULL;
  317.     _fSourcePartSU = (ODStorageUnit*) kODNULL;
  318.     _fAutoUpdate = kODFalse;
  319.     _fNewUpdateID = kODUnknownUpdate;
  320.     _fUpdateID = kODUnknownUpdate;
  321.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  322.     _fChangeTime = 0;
  323.     _fChangeCount = 1;
  324.     _fChangeLimit = 1;
  325.     _fDirty = kNotDirty;
  326.     _fKindsUsed = (ODTypeList*) kODNULL;
  327.     _fCleared = kODFalse;
  328. }
  329.  
  330. //------------------------------------------------------------------------------
  331. // ODBaseLinkSource: somUninit
  332. //------------------------------------------------------------------------------
  333.  
  334. SOM_Scope void  SOMLINK ODBaseLinkSourcesomUninit(ODBaseLinkSource *somSelf)
  335. {
  336.     /* ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf); */
  337.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somUninit");
  338.  
  339.     parent_somUninit(somSelf);
  340. }
  341.  
  342. //------------------------------------------------------------------------------
  343. // ODBaseLinkSource: InitBaseLinkSource
  344. //------------------------------------------------------------------------------
  345.  
  346. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSource(ODBaseLinkSource *somSelf, Environment *ev,
  347.         ODStorageUnit* storageUnit,
  348.         ODPart* sourcePart)
  349. {
  350.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  351.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSource");
  352.  
  353.     SOM_CATCH return;
  354.  
  355.     somSelf->InitPersistentObject(ev, storageUnit);
  356.     InitDateInfo(ev, storageUnit);
  357.  
  358.     _fUpdateID = storageUnit->GetSession(ev)->UniqueUpdateID(ev);
  359.  
  360.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  361.  
  362.     if ( sourcePart != (ODPart*) kODNULL )
  363.     {
  364.         _fSourcePartSU = sourcePart->GetStorageUnit(ev);
  365.         _fSourcePartSU->Acquire(ev);
  366.         _fAutoUpdate = kODTrue;
  367.     }
  368.  
  369.     ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  370.  
  371.     _fContentSU = su->GetDraft(ev)->CreateStorageUnit(ev);
  372.     ODSetISOStrProp(ev, _fContentSU, kODPropStorageUnitType, kODISOStr, kODLinkContent);
  373.  
  374.     ODSUAddPropValue(ev, su, kODPropUpdateID, kODULong);
  375.     ODSUAddPropValue(ev, su, kODPropChangeLimit, kODULong);
  376.     ODSUAddPropValue(ev, su, kODPropChangeTime, kODTime_T);
  377.     ODSUAddPropValue(ev, su, kODPropAutoUpdate, kODBoolean);
  378.     ODSUAddPropValue(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef);
  379.     ODSUAddPropValue(ev, su, kODPropLink, kODWeakStorageUnitRef);
  380.  
  381.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  382.         ODSUAddPropValue(ev, su, kODPropSourcePart, kODWeakStorageUnitRef);
  383.  
  384.     somSelf->SetBaseLinkSourceDirty(ev, kAllDirty);
  385. }
  386.  
  387. //------------------------------------------------------------------------------
  388. // ODBaseLinkSource: InitBaseLinkSourceFromStorage
  389. //------------------------------------------------------------------------------
  390.  
  391. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSourceFromStorage(ODBaseLinkSource *somSelf, Environment *ev,
  392.         ODStorageUnit* storageUnit)
  393. {
  394.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  395.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSourceFromStorage");
  396.  
  397.     SOM_CATCH return;
  398.  
  399.     somSelf->InitPersistentObjectFromStorage(ev, storageUnit);
  400.     InitDateInfo(ev, storageUnit);
  401.  
  402.     _fContentSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, ODGetStrongSURefProp(ev, storageUnit, kODPropLinkContentSU, kODStrongStorageUnitRef));
  403.     _fUpdateID = ODGetULongProp(ev, storageUnit, kODPropUpdateID, kODULong);
  404.     _fChangeLimit = ODGetULongProp(ev, storageUnit, kODPropChangeLimit, kODULong);
  405.     _fChangeTime = ODGetTime_TProp(ev, storageUnit, kODPropChangeTime, kODTime_T);
  406.     _fAutoUpdate = ODGetBooleanProp(ev, storageUnit, kODPropAutoUpdate, kODBoolean);
  407.  
  408.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  409.  
  410.     if ( storageUnit->Exists(ev, kODPropContentKindsUsed, 0, 0) )
  411.     {
  412.         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)->CreateTypeList(ev, kODNULL);
  413.         ODGetTypeListProp(ev, storageUnit, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  414.     }
  415.  
  416.     if ( storageUnit->Exists(ev, kODPropLink, 0, 0) )
  417.     {
  418.         ODID linkID = ODGetWeakSURefProp(ev, storageUnit, kODPropLink, kODWeakStorageUnitRef);
  419.         if ( linkID == kODNULLID )
  420.             somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  421.         else
  422.             _fLink = storageUnit->GetDraft(ev)->AcquireLink(ev, linkID, (ODLinkSpec*) kODNULL);
  423.     }
  424.  
  425.     if ( storageUnit->Exists(ev, kODPropSourcePart, 0, 0) )
  426.     {
  427.         ODID sourcePartID = ODGetWeakSURefProp(ev, storageUnit, kODPropSourcePart, kODWeakStorageUnitRef);
  428.         if ( sourcePartID == kODNULLID )
  429.             somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  430.         else
  431.             _fSourcePartSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, sourcePartID);
  432.     }
  433. }
  434.  
  435. //------------------------------------------------------------------------------
  436. // ODBaseLinkSource::Externalize (OVERRIDE)
  437. //------------------------------------------------------------------------------
  438.  
  439. SOM_Scope void  SOMLINK ODBaseLinkSourceExternalize(ODBaseLinkSource *somSelf, Environment *ev)
  440. {
  441.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  442.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Externalize");
  443.  
  444.     SOM_CATCH return;
  445.  
  446.     parent_Externalize(somSelf,ev);
  447.  
  448.     RemovePromisedContent(ev, _fContentSU);
  449.  
  450.     if ( _fDirty )
  451.     {
  452.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  453.  
  454.         if ( _fDirty & kContentSUDirty )
  455.             ODSetStrongSURefProp(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef, _fContentSU->GetID(ev));
  456.  
  457.         if ( _fDirty & kUpdateIDDirty )
  458.             ODSetULongProp(ev, su, kODPropUpdateID, kODULong, _fUpdateID);
  459.  
  460.         if ( _fDirty & kChangeLimitDirty )
  461.             ODSetULongProp(ev, su, kODPropChangeLimit, kODULong, _fChangeLimit);
  462.  
  463.         if ( _fDirty & kChangeTimeDirty )
  464.             ODSetTime_TProp(ev, su, kODPropChangeTime, kODTime_T, _fChangeTime);
  465.  
  466.         if ( _fDirty & kAutoUpdateDirty )
  467.             ODSetBooleanProp(ev, su, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  468.     
  469.         if ( _fDirty & kKindsUsedDirty )
  470.         {
  471.             if ( _fKindsUsed == kODNULL )
  472.                 ODSURemoveProperty(ev, su, kODPropContentKindsUsed);
  473.             else
  474.                 ODSetTypeListProp(ev, su, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  475.         }
  476.         
  477.         if ( _fDirty & kLinkDirty )
  478.         {
  479.             if ( _fLink == (ODLink*) kODNULL )
  480.                 ODSURemoveProperty(ev, su, kODPropLink);
  481.             else
  482.                 ODSetWeakSURefProp(ev, su, kODPropLink, kODWeakStorageUnitRef, _fLink->GetStorageUnit(ev)->GetID(ev));
  483.         }
  484.  
  485.         if ( _fDirty & kSourcePartDirty )
  486.         {
  487.             if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  488.                 ODSURemoveProperty(ev, su, kODPropSourcePart);
  489.             else
  490.                 ODSetWeakSURefProp(ev, su, kODPropSourcePart, kODWeakStorageUnitRef, _fSourcePartSU->GetID(ev));
  491.         }
  492.  
  493.         _fDirty = kNotDirty;
  494.     }
  495. }
  496.  
  497. //------------------------------------------------------------------------------
  498. // ODBaseLinkSource: CloneInto (OVERRIDE)
  499. //------------------------------------------------------------------------------
  500.  
  501. SOM_Scope void  SOMLINK ODBaseLinkSourceCloneInto(ODBaseLinkSource *somSelf, Environment *ev,
  502.         ODDraftKey key,
  503.         ODStorageUnit* toSU,
  504.         ODFrame* scopeFrame)
  505. {
  506.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  507.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","CloneInto");
  508.  
  509.     SOM_CATCH return;
  510.     
  511.     // If one of our properties already exists, this object has been cloned already
  512.     if ( toSU->Exists(ev, kODPropLink, kODWeakStorageUnitRef, 0) )
  513.         return;
  514.  
  515.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  516.  
  517.     RemovePromisedContent(ev, _fContentSU);
  518.  
  519.     CloneDateInfo(ev, somSelf->GetStorageUnit(ev), toSU);
  520.     
  521.     ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  522.  
  523.     ODSetULongProp(ev, toSU, kODPropUpdateID, kODULong, _fUpdateID);
  524.     ODSetULongProp(ev, toSU, kODPropChangeLimit, kODULong, 1);
  525.     ODSetTime_TProp(ev, toSU, kODPropChangeTime, kODTime_T, _fChangeTime);
  526.     ODSetBooleanProp(ev, toSU, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  527.  
  528.     ODID clonedLinkContentID = draft->Clone(ev, key, _fContentSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  529.     ODSetStrongSURefProp(ev, toSU, kODPropLinkContentSU, kODStrongStorageUnitRef, clonedLinkContentID);
  530.  
  531.     if ( _fKindsUsed != kODNULL )
  532.         ODSetTypeListProp(ev, toSU, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  533.  
  534.     if ( _fLink != (ODLink*) kODNULL )
  535.     {
  536.         ODID clonedLinkSourceID = draft->WeakClone(ev, key, _fLink->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  537.         ODSetWeakSURefProp(ev, toSU, kODPropLink, kODWeakStorageUnitRef, clonedLinkSourceID);
  538.     }
  539.  
  540.     // The source part should only be kODNULL for links imported from another draft.
  541.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  542.     {
  543.         ODID clonedSourcePartID = draft->WeakClone(ev, key, _fSourcePartSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  544.         ODSetWeakSURefProp(ev, toSU, kODPropSourcePart, kODWeakStorageUnitRef, clonedSourcePartID);
  545.     }
  546. }
  547.  
  548. //------------------------------------------------------------------------------
  549. // ODBaseLinkSource: ReleaseAll (OVERRIDE)
  550. //------------------------------------------------------------------------------
  551.  
  552. SOM_Scope void  SOMLINK ODBaseLinkSourceReleaseAll(ODBaseLinkSource *somSelf, Environment *ev)
  553. {
  554.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  555.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ReleaseAll");
  556.  
  557.     SOM_CATCH return;
  558.  
  559.     parent_ReleaseAll(somSelf,ev);
  560.  
  561.     ODReleaseObject(ev, _fContentSU);
  562.     ODReleaseObject(ev, _fLink);
  563.     ODReleaseObject(ev, _fSourcePartSU);
  564. }
  565.  
  566. //------------------------------------------------------------------------------
  567. // ODBaseLinkSource: SetBaseLinkSourceDirty
  568. //------------------------------------------------------------------------------
  569.  
  570. SOM_Scope void  SOMLINK ODBaseLinkSourceSetBaseLinkSourceDirty(ODBaseLinkSource *somSelf, Environment *ev,
  571.     ODULong dirtyProperty)
  572. {
  573.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  574.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetBaseLinkSourceDirty");
  575.  
  576.     SOM_TRY    
  577.         _fDirty |= dirtyProperty;
  578.  
  579.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  580.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  581.             draft->SetChangedFromPrev(ev);
  582.     SOM_CATCH_ALL
  583.     SOM_ENDTRY
  584. }
  585.  
  586. //------------------------------------------------------------------------------
  587. // ODBaseLinkSource: ShowLinkSourceInfo
  588. //------------------------------------------------------------------------------
  589.  
  590. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceShowLinkSourceInfo(ODBaseLinkSource *somSelf, Environment *ev,
  591.         ODFacet* facet,
  592.         ODUpdateID change,
  593.         ODBoolean changesAllowed,
  594.         ODLinkInfoResult* infoResult)
  595. {
  596.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  597.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowLinkSourceInfo");
  598.  
  599.     ODBoolean result = kODFalse;
  600.  
  601.     SOM_CATCH return kODFalse;
  602.     
  603.     THROW_IF_NULL(facet, kODErrNullFacetInput);
  604.     THROW_IF_NULL(infoResult, kODErrNullLinkInfoResultInput);
  605.     THROW_IF_NULL(_fLink, kODErrBrokenLink);
  606.  
  607.     ODSession* session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  608.     ODTypeToken modalFocus = session->Tokenize(ev, kODModalFocus);
  609.     ODArbitrator* arbitrator = session->GetArbitrator(ev);
  610.     TempODFrame currentOwner = arbitrator->AcquireFocusOwner(ev, modalFocus);
  611.  
  612.     if ( arbitrator->RequestFocus(ev, modalFocus, facet->GetFrame(ev)) )
  613.     {
  614.         infoResult->autoUpdate = _fAutoUpdate;
  615.     
  616.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  617.  
  618.         result = ShowLinkSourceInfo(somSelf, change, changesAllowed, infoResult);
  619.  
  620.         session->GetWindowState(ev)->ActivateFrontWindows(ev);
  621.  
  622.         arbitrator->TransferFocus(ev, modalFocus, facet->GetFrame(ev), currentOwner);
  623.     }
  624.     else
  625.     {
  626.         SysBeep(2);
  627.     }
  628.     return result;
  629. }
  630.  
  631. //------------------------------------------------------------------------------
  632. // ODBaseLinkSource: Lock
  633. //------------------------------------------------------------------------------
  634.  
  635. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceLock(ODBaseLinkSource *somSelf, Environment *ev,
  636.         ODULong wait,
  637.         ODLinkKey* key)
  638. {
  639.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  640.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Lock");
  641.  
  642.     ODUnused(wait);
  643.  
  644.     if ( _fLink == (ODLink*) kODNULL )
  645.     {
  646.         ODSetSOMException(ev, kODErrBrokenLink);
  647.         return kODFalse;
  648.     }
  649.  
  650.     TRY    // Don't use SOM_TRY as we do _not_ want to return an exception!
  651.  
  652.     *key = (ODLinkKey) somSelf->GetStorageUnit(ev)->Lock(ev, 0);
  653.     
  654.     _fCleared = kODFalse;
  655.     _fNewUpdateID = kODUnknownUpdate;
  656.     
  657.     CATCH_ALL
  658.         *key = kODNullKey;
  659.         // Don't reraise, just return
  660.     ENDTRY
  661.  
  662.     return (*key != kODNullKey);
  663. }
  664.  
  665. //------------------------------------------------------------------------------
  666. // ODBaseLinkSource: Unlock
  667. //------------------------------------------------------------------------------
  668.  
  669. SOM_Scope void  SOMLINK ODBaseLinkSourceUnlock(ODBaseLinkSource *somSelf, Environment *ev,
  670.         ODLinkKey key)
  671. {
  672.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  673.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Unlock");
  674.  
  675.     SOM_TRY
  676.  
  677.         // Force fulfilling of promises for content kinds used by current destinations
  678.         if ( _fCleared && _fKindsUsed )
  679.         {
  680.             ODBoolean allUsedKindsPresent = kODTrue; ODVolatile(allUsedKindsPresent);
  681.         
  682.             ODTypeListIterator* iter = kODNULL; ODVolatile(iter);
  683.             TRY
  684.                 iter = _fKindsUsed->CreateTypeListIterator(ev);
  685.         
  686.                 for (ODType kind = iter->First(ev);
  687.                     iter->IsNotComplete(ev);
  688.                     kind = iter->Next(ev))
  689.                 {
  690.                     if ( ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kind) )
  691.                     {
  692.                         if ( _fContentSU->IsPromiseValue(ev) )
  693.                         {
  694.                             // Force part to fulfill its promise
  695.                             TRY
  696.                                 ODULong size = _fContentSU->GetSize(ev);
  697.                             CATCH_ALL
  698.                                 allUsedKindsPresent = kODFalse;
  699.                             ENDTRY
  700.                         }
  701.                     }
  702.                     else
  703.                     {
  704.                         allUsedKindsPresent = kODFalse;
  705.                     }
  706.                     ODDisposePtr(kind);
  707.                 }
  708.             CATCH_ALL
  709.                 allUsedKindsPresent = kODFalse;
  710.             ENDTRY
  711.             ODDeleteObject(iter);
  712.         
  713.             if ( allUsedKindsPresent )
  714.             {
  715.                 ODDeleteObject(_fKindsUsed);
  716.                 somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  717.             }
  718.         }
  719.  
  720.         _fCleared = kODFalse;
  721.  
  722.         // Any unlocking action needs to be performed before calling UpdateDependents(),
  723.         // since that will cause dependents to lock and unlock their link, which delegates
  724.         // to this object. 
  725.     
  726.         somSelf->GetStorageUnit(ev)->Unlock(ev, (ODStorageUnitKey) key);
  727.     
  728.         if ( _fNewUpdateID != kODUnknownUpdate )
  729.         {
  730.             ODBoolean notifyDependents = kODFalse;
  731.     
  732.             time(&_fChangeTime);
  733.             somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  734.  
  735.             if ( _fUpdateID != _fNewUpdateID )
  736.             {
  737.                 // Link updated with different change ID than last time
  738.                 _fChangeCount = 1;
  739.                 _fUpdateID = _fNewUpdateID;
  740.                 somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  741.                 notifyDependents = kODTrue;
  742.                 
  743.                 if ( _fSuspended )
  744.                     _fUpdatedAfterSuspended = kODTrue;
  745.             }
  746.             else if ( ++_fChangeCount <= _fChangeLimit )
  747.             {
  748.                 // Same change but user previously continued beyond this iteration
  749.                 notifyDependents = kODTrue;
  750.             }
  751.             else
  752.             {
  753.                 ODLinkManager* linkMgr = 
  754.                     somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  755.                 ODLinkUpdateResult updateResult = linkMgr->ShowLinkUpdateAlert(ev, somSelf);
  756.                     
  757.                 if ( updateResult == kODLinkUpdateContinue )
  758.                 {
  759.                     // User continued propagating this update
  760.                     ++_fChangeLimit;
  761.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  762.                     notifyDependents = kODTrue;
  763.                 }
  764.                 else if ( updateResult == kODLinkUpdateStop )
  765.                 {
  766.                     // User cancelled propagating this update
  767.                     _fChangeLimit = 1;
  768.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  769.                 }
  770.                 else // updateResult == kODLinkUpdateSuspend
  771.                 {
  772.                     _fSuspended = kODTrue;
  773.                 }
  774.             }
  775.     
  776.             _fNewUpdateID = kODUnknownUpdate;
  777.     
  778.             if ( notifyDependents && !_fSuspended && (_fLink != (ODLink*) kODNULL) )
  779.             {
  780.                 // Ignore errors returned by UpdateDependents
  781.                 TRY
  782.                     _fLink->UpdateDependents(ev);
  783.                 CATCH_ALL
  784.                 ENDTRY
  785.             }
  786.         }
  787.     
  788.     SOM_CATCH_ALL
  789.     
  790.     SOM_ENDTRY
  791. }
  792.  
  793.  
  794. //------------------------------------------------------------------------------
  795. // ODBaseLinkSource: LinkUpdateAlertCompleted
  796. //------------------------------------------------------------------------------
  797.  
  798. SOM_Scope void  SOMLINK ODBaseLinkSourceLinkUpdateAlertCompleted(ODBaseLinkSource *somSelf, Environment *ev,
  799.         ODLinkUpdateResult updateResult)
  800. {
  801.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  802.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","LinkUpdateAlertCompleted");
  803.  
  804.     ODBoolean notifyDependents = kODFalse;
  805.     
  806.     SOM_TRY
  807.     
  808.         // Get and reset these booleans atomically here to avoid possible 
  809.         // confusion from setting them again while updating dependents:
  810.         ODBoolean suspended = _fSuspended;
  811.         ODBoolean updatedAfterSuspended = _fUpdatedAfterSuspended;
  812.         _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  813.         
  814.         if ( updateResult == kODLinkUpdateContinue )
  815.         {
  816.             // User continued propagating this update
  817.             ++_fChangeLimit;
  818.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  819.             notifyDependents = kODTrue;
  820.         }
  821.         else if ( updateResult == kODLinkUpdateStop )
  822.         {
  823.             // User cancelled propagating this update
  824.             _fChangeLimit = 1;
  825.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  826.             
  827.             if ( updatedAfterSuspended )
  828.                 notifyDependents = kODTrue;
  829.         }
  830.  
  831.         if ( notifyDependents && (_fLink != (ODLink*) kODNULL) )
  832.         {
  833.             // Ignore errors returned by UpdateDependents
  834.             TRY
  835.                 _fLink->UpdateDependents(ev);
  836.             CATCH_ALL
  837.             ENDTRY
  838.         }
  839.  
  840.     SOM_CATCH_ALL
  841.     
  842.     SOM_ENDTRY
  843. }
  844.  
  845. //------------------------------------------------------------------------------
  846. // ODBaseLinkSource: KeyValid
  847. //------------------------------------------------------------------------------
  848.  
  849. SOM_Scope void  SOMLINK ODBaseLinkSourceKeyValid(ODBaseLinkSource *somSelf, Environment *ev,
  850.         ODLinkKey key)
  851. {
  852.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  853.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","KeyValid");
  854.  
  855.     SOM_CATCH return;
  856.  
  857.     if (key == kODNullKey)
  858.         ODSetSOMException(ev, kODErrInvalidLinkKey);
  859.     else
  860.     {
  861.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  862.         ODStorageUnitKey suKey = su->Lock(ev, (ODStorageUnitKey) key);
  863.         su->Unlock(ev, suKey);
  864.     }
  865. }
  866.  
  867. //------------------------------------------------------------------------------
  868. // ODBaseLinkSource: GetContentStorageUnit
  869. //------------------------------------------------------------------------------
  870.  
  871. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceGetContentStorageUnit(ODBaseLinkSource *somSelf, Environment *ev,
  872.         ODLinkKey key)
  873. {
  874.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  875.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetContentStorageUnit");
  876.  
  877.     SOM_CATCH return (ODStorageUnit*) kODNULL;
  878.  
  879.     somSelf->KeyValid(ev, key);
  880.  
  881.     return _fContentSU;
  882. }
  883.  
  884. //------------------------------------------------------------------------------
  885. // ODBaseLinkSource: ContentUpdated
  886. //------------------------------------------------------------------------------
  887.  
  888. SOM_Scope void  SOMLINK ODBaseLinkSourceContentUpdated(ODBaseLinkSource *somSelf, Environment *ev,
  889.         ODUpdateID id,
  890.         ODLinkKey key)
  891. {
  892.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  893.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ContentUpdated");
  894.  
  895.     SOM_TRY
  896.  
  897.         somSelf->KeyValid(ev, key);
  898.  
  899.         if ( id == kODUnknownUpdate )
  900.             THROW(kODErrUnknownUpdateID);
  901.  
  902.         _fNewUpdateID = id;
  903.     
  904.     SOM_CATCH_ALL
  905.     
  906.     SOM_ENDTRY
  907. }
  908.  
  909. //------------------------------------------------------------------------------
  910. // ODBaseLinkSource: Clear
  911. //------------------------------------------------------------------------------
  912.  
  913. SOM_Scope void  SOMLINK ODBaseLinkSourceClear(ODBaseLinkSource *somSelf, Environment *ev,
  914.         ODUpdateID id,
  915.         ODLinkKey key)
  916. {
  917.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  918.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Clear");
  919.  
  920.     ODValueType kind = kODNULL;    ODVolatile(kind);
  921.  
  922.     SOM_TRY
  923.  
  924.         somSelf->KeyValid(ev, key);
  925.  
  926.         // Fail immediately if this draft can't be changed
  927.         ODDraftPermissions permissions = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetPermissions(ev);
  928.         if (!HAS_WRITE_ACCESS(permissions))
  929.             THROW(kODErrInvalidPermissions);
  930.  
  931.         if ( id == kODUnknownUpdate )
  932.             THROW(kODErrUnknownUpdateID);
  933.  
  934.         // If id is the current id, don't notify destinations unless ContentUpdated is called.
  935.         if ( id != _fUpdateID )
  936.             _fNewUpdateID = id;
  937.         
  938.         // Add each non-promise value type in the contents property to _fKindsUsed,
  939.         // then remove the contents property.
  940.         if (ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kODNULL) )
  941.         {
  942.             ODULong numValues = _fContentSU->CountValues(ev);    
  943.             ODULong kindIndex;
  944.             
  945.             for (kindIndex = 0; kindIndex < numValues; kindIndex++)
  946.             {
  947.                 _fContentSU->Focus(ev, kODPropContents, kODPosUndefined, kODTypeAll, 0, kODPosNextSib);
  948.                 if ( !_fContentSU->IsPromiseValue(ev) )
  949.                 {
  950.                     if ( _fKindsUsed == kODNULL )
  951.                         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)
  952.                                         ->CreateTypeList(ev, kODNULL);
  953.                     kind = _fContentSU->GetType(ev);
  954.                     _fKindsUsed->AddLast(ev, kind);
  955.                     ODDisposePtr(kind);
  956.                     kind = kODNULL;
  957.                     somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  958.                 }
  959.             }
  960.             ODSURemoveProperty(ev, _fContentSU, kODPropContents);
  961.  
  962.             RemoveDataInterchangeProperties(ev, _fContentSU, kODFalse);
  963.             
  964.             _fCleared = kODTrue;
  965.         }
  966.  
  967.     SOM_CATCH_ALL
  968.     
  969.         ODDisposePtr(kind);
  970.  
  971.     SOM_ENDTRY
  972. }
  973.  
  974. //------------------------------------------------------------------------------
  975. // ODBaseLinkSource: GetUpdateID
  976. //------------------------------------------------------------------------------
  977.  
  978. SOM_Scope ODUpdateID  SOMLINK ODBaseLinkSourceGetUpdateID(ODBaseLinkSource *somSelf, Environment *ev)
  979. {
  980.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  981.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetUpdateID");
  982.  
  983.     return _fUpdateID;
  984. }
  985.  
  986. //------------------------------------------------------------------------------
  987. // ODBaseLinkSource: SetUpdateID
  988. //------------------------------------------------------------------------------
  989.  
  990. SOM_Scope void  SOMLINK ODBaseLinkSourceSetUpdateID(ODBaseLinkSource *somSelf, Environment *ev,
  991.         ODUpdateID updateID,
  992.         ODLinkKey key)
  993. {
  994.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  995.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetUpdateID");
  996.  
  997.     SOM_CATCH return;
  998.  
  999.     somSelf->KeyValid(ev, key);
  1000.  
  1001.     if ( updateID != _fUpdateID )
  1002.     {
  1003.         _fUpdateID = updateID;
  1004.         somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  1005.     }
  1006. }
  1007.  
  1008. //------------------------------------------------------------------------------
  1009. // ODBaseLinkSource: GetChangeTime
  1010. //------------------------------------------------------------------------------
  1011.  
  1012. SOM_Scope ODTime  SOMLINK ODBaseLinkSourceGetChangeTime(ODBaseLinkSource *somSelf, Environment *ev)
  1013. {
  1014.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1015.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetChangeTime");
  1016.  
  1017.     return _fChangeTime;
  1018. }
  1019.  
  1020. //------------------------------------------------------------------------------
  1021. // ODBaseLinkSource: SetChangeTime
  1022. //------------------------------------------------------------------------------
  1023.  
  1024. SOM_Scope void  SOMLINK ODBaseLinkSourceSetChangeTime(ODBaseLinkSource *somSelf, Environment *ev,
  1025.         ODTime changeTime,
  1026.         ODLinkKey key)
  1027. {
  1028.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1029.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetChangeTime");
  1030.  
  1031.     SOM_CATCH return;
  1032.  
  1033.     somSelf->KeyValid(ev, key);
  1034.  
  1035.     _fChangeTime = changeTime;
  1036.     somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  1037. }
  1038.  
  1039. //------------------------------------------------------------------------------
  1040. // ODBaseLinkSource: IsAutoUpdate
  1041. //------------------------------------------------------------------------------
  1042.  
  1043. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceIsAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev)
  1044. {
  1045.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1046.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","IsAutoUpdate");
  1047.  
  1048.     return _fAutoUpdate;
  1049. }
  1050.  
  1051. //------------------------------------------------------------------------------
  1052. // ODBaseLinkSource: SetAutoUpdate
  1053. //------------------------------------------------------------------------------
  1054.  
  1055. SOM_Scope void  SOMLINK ODBaseLinkSourceSetAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev,
  1056.         ODBoolean automatic)
  1057. {
  1058.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1059.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetAutoUpdate");
  1060.  
  1061.     SOM_TRY
  1062.     _fAutoUpdate = automatic;
  1063.     somSelf->SetBaseLinkSourceDirty(ev, kAutoUpdateDirty);
  1064.     SOM_CATCH_ALL
  1065.     SOM_ENDTRY
  1066. }
  1067.  
  1068. //------------------------------------------------------------------------------
  1069. // ODBaseLinkSource: GetLink
  1070. //------------------------------------------------------------------------------
  1071.  
  1072. SOM_Scope ODLink*  SOMLINK ODBaseLinkSourceGetLink(ODBaseLinkSource *somSelf, Environment *ev)
  1073. {
  1074.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1075.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetLink");
  1076.  
  1077.     if ( _fLink == (ODLink*) kODNULL )
  1078.     {
  1079.         ODSetSOMException(ev, kODErrBrokenLink);
  1080.         return (ODLink*) kODNULL;
  1081.     }
  1082.  
  1083.     return _fLink;
  1084. }
  1085.  
  1086. //------------------------------------------------------------------------------
  1087. // ODBaseLinkSource: SetLink
  1088. //------------------------------------------------------------------------------
  1089.  
  1090. SOM_Scope void  SOMLINK ODBaseLinkSourceSetLink(ODBaseLinkSource *somSelf, Environment *ev,
  1091.         ODLink* link)
  1092. {
  1093.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1094.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetLink");
  1095.  
  1096.     SOM_TRY
  1097.     
  1098.     if ( !ODObjectsAreEqual(ev, _fLink, link) )
  1099.     {
  1100.         ODReleaseObject(ev, _fLink);
  1101.     
  1102.         _fLink = link;
  1103.         if ( _fLink != (ODLink*) kODNULL )
  1104.             _fLink->Acquire(ev);
  1105.  
  1106.         somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  1107.     }
  1108.     
  1109.     SOM_CATCH_ALL
  1110.     SOM_ENDTRY
  1111. }
  1112.  
  1113. //------------------------------------------------------------------------------
  1114. // ODBaseLinkSource: AcquireSourcePart
  1115. //------------------------------------------------------------------------------
  1116.  
  1117. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceAcquireSourcePart(ODBaseLinkSource *somSelf, Environment *ev)
  1118. {
  1119.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1120.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","AcquireSourcePart");
  1121.  
  1122.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL ) {
  1123.         SOM_TRY
  1124.         _fSourcePartSU->Acquire(ev);
  1125.         SOM_CATCH_ALL
  1126.         SOM_ENDTRY
  1127.     }
  1128.     return _fSourcePartSU;
  1129. }
  1130.  
  1131. //------------------------------------------------------------------------------
  1132. // ODBaseLinkSource: SetSourcePart
  1133. //------------------------------------------------------------------------------
  1134.  
  1135. SOM_Scope void  SOMLINK ODBaseLinkSourceSetSourcePart(ODBaseLinkSource *somSelf, Environment *ev,
  1136.         ODStorageUnit* sourcePartSU)
  1137. {
  1138.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1139.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetSourcePart");
  1140.  
  1141.     SOM_CATCH return;
  1142.  
  1143.     if ( !ODObjectsAreEqual(ev, _fSourcePartSU, sourcePartSU) )
  1144.     {
  1145.         ODReleaseObject(ev, _fSourcePartSU);
  1146.     
  1147.         _fSourcePartSU = sourcePartSU;
  1148.         if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  1149.             _fSourcePartSU->Acquire(ev);
  1150.     
  1151.         somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  1152.     }
  1153. }
  1154.  
  1155. //------------------------------------------------------------------------------
  1156. // ODBaseLinkSource: ShowSourceContent
  1157. //------------------------------------------------------------------------------
  1158.  
  1159. SOM_Scope void  SOMLINK ODBaseLinkSourceShowSourceContent(ODBaseLinkSource *somSelf, Environment *ev)
  1160. {
  1161.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1162.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowSourceContent");
  1163.  
  1164.     SOM_CATCH return;
  1165.  
  1166.     if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  1167.         THROW(kODErrBrokenLinkSource);
  1168.     
  1169.     TempODPart part = somSelf->GetStorageUnit(ev)->GetDraft(ev)->AcquirePart(ev, _fSourcePartSU->GetID(ev));
  1170.     part->RevealLink(ev, (ODLinkSource*) somSelf);
  1171. }
  1172.  
  1173. //------------------------------------------------------------------------------
  1174. // RemovePromisedContent
  1175. //------------------------------------------------------------------------------
  1176.  
  1177. static void RemovePromisedContent(Environment *ev, ODStorageUnit* su)
  1178. {
  1179.     // Remove value types that still contain promises
  1180.     if ( su && ODSUExistsThenFocus(ev, su, kODPropContents, kODNULL) )
  1181.     {
  1182.         ODULong numValues = su->CountValues(ev);    
  1183.         ODULong kindIndex;
  1184.         
  1185.         for (kindIndex = 0; kindIndex < numValues; kindIndex++)
  1186.         {
  1187.             su->Focus(ev, kODPropContents, kODPosUndefined, kODTypeAll, 0, kODPosNextSib);
  1188.             if ( su->IsPromiseValue(ev) )
  1189.                 su->Remove(ev);
  1190.         }
  1191.     }
  1192. }
  1193.